package com.atguigu.daijia.driver.util;

import com.atguigu.daijia.common.execption.GuiguException;
import com.atguigu.daijia.common.result.ResultCodeEnum;
import com.atguigu.daijia.driver.config.CosConfigProperties;
import com.atguigu.daijia.model.entity.driver.DriverInfo;
import com.qcloud.cos.COSClient;
import com.qcloud.cos.ClientConfig;
import com.qcloud.cos.auth.BasicCOSCredentials;
import com.qcloud.cos.auth.COSCredentials;
import com.qcloud.cos.http.HttpMethodName;
import com.qcloud.cos.http.HttpProtocol;
import com.qcloud.cos.model.*;
import com.qcloud.cos.region.Region;
import com.qcloud.cos.utils.Base64;
import com.tencentcloudapi.common.AbstractModel;
import com.tencentcloudapi.common.Credential;
import com.tencentcloudapi.common.profile.ClientProfile;
import com.tencentcloudapi.common.profile.HttpProfile;
import com.tencentcloudapi.iai.v20180301.IaiClient;
import com.tencentcloudapi.iai.v20180301.models.CreatePersonRequest;
import com.tencentcloudapi.iai.v20180301.models.CreatePersonResponse;
import com.tencentcloudapi.ocr.v20181119.OcrClient;
import com.tencentcloudapi.ocr.v20181119.models.DriverLicenseOCRRequest;
import com.tencentcloudapi.ocr.v20181119.models.DriverLicenseOCRResponse;
import com.tencentcloudapi.ocr.v20181119.models.IDCardOCRRequest;
import com.tencentcloudapi.ocr.v20181119.models.IDCardOCRResponse;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.joda.time.DateTime;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.InputStream;
import java.net.URL;
import java.util.Date;

/**
 * 腾讯云接口操作
 * @author moningxi
 */
@Component
@Slf4j
public class CloudApiOperator {
    @Resource
    private CosConfigProperties cosConfigProperties;

    // 初始化配置
    public COSClient getCosClient() {
        COSCredentials cred = new BasicCOSCredentials(cosConfigProperties.getSecretId(), cosConfigProperties.getSecretKey());
        Region region = new Region(cosConfigProperties.getRegion());
        ClientConfig clientConfig = new ClientConfig(region);
        clientConfig.setHttpProtocol(HttpProtocol.https);
        return new COSClient(cred, clientConfig);
    }

    public OcrClient getOcrClient() {
        Credential cred = new Credential(cosConfigProperties.getSecretId(), cosConfigProperties.getSecretKey());
        // 实例化一个http选项，可选的，没有特殊需求可以跳过
        HttpProfile httpProfile = new HttpProfile();
        httpProfile.setEndpoint("ocr.tencentcloudapi.com");
        // 实例化一个client选项，可选的，没有特殊需求可以跳过
        ClientProfile clientProfile = new ClientProfile();
        clientProfile.setHttpProfile(httpProfile);
        // 实例化要请求产品的client对象,clientProfile是可选的
        return new OcrClient(cred, "ap-beijing", clientProfile);
    }

    public IaiClient getIaiClient() {
        Credential cred = new Credential(cosConfigProperties.getSecretId(), cosConfigProperties.getSecretKey());
        // 实例化一个http选项，可选的，没有特殊需求可以跳过
        HttpProfile httpProfile = new HttpProfile();
        httpProfile.setEndpoint("iai.tencentcloudapi.com");
        // 实例化一个client选项，可选的，没有特殊需求可以跳过
        ClientProfile clientProfile = new ClientProfile();
        clientProfile.setHttpProfile(httpProfile);
        // 实例化要请求产品的client对象,clientProfile是可选的
        return new IaiClient(cred, cosConfigProperties.getRegion(), clientProfile);
    }

    /**
     * 文件上传
     */
    public void upload(String uploadPath, InputStream stream, ObjectMetadata meta) {
        // 指定文件将要存放的存储桶
        String bucketName = cosConfigProperties.getBucketName();
        // 指定文件上传到 COS 上的路径，即对象键。例如对象键为 folder/picture.jpg，则表示将文件 picture.jpg 上传到 folder 路径下
        PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, uploadPath, stream, meta);
        putObjectRequest.setStorageClass(StorageClass.Standard);
        COSClient cosClient = getCosClient();
        PutObjectResult putObjectResult = cosClient.putObject(putObjectRequest);
        cosClient.shutdown();
    }

    /**
     * 获取临时签名url
     */
    public String getImageUrl(String path) {
        GeneratePresignedUrlRequest request =
                new GeneratePresignedUrlRequest(cosConfigProperties.getBucketName(),
                        path, HttpMethodName.GET);
        //设置临时URL有效期为15分钟
        Date date = new DateTime().plusMinutes(15).toDate();
        request.setExpiration(date);
        //调用方法获取
        COSClient cosClient = getCosClient();
        URL url = cosClient.generatePresignedUrl(request);
        cosClient.shutdown();
        return url.toString();
    }

    /**
     * 身份证识别
     */
    public IDCardOCRResponse idCardOcr(MultipartFile file) {
        try {
            //图片转换base64格式字符串
            byte[] base64 = org.apache.commons.codec.binary.Base64.encodeBase64(file.getBytes());
            String fileBase64 = new String(base64);
            OcrClient client = getOcrClient();
            // 实例化一个请求对象,每个接口都会对应一个request对象
            IDCardOCRRequest req = new IDCardOCRRequest();
            req.setImageBase64(fileBase64);

            // 返回的resp是一个IDCardOCRResponse的实例，与请求对象对应
            IDCardOCRResponse resp = client.IDCardOCR(req);

            // 输出json格式的字符串回包
            System.out.println(AbstractModel.toJsonString(resp));
            return resp;
        } catch (Exception e) {
            log.error("身份证识别失败：{}", e.getMessage());
            throw new GuiguException(ResultCodeEnum.DATA_ERROR);
        }
    }

    /**
     * 驾驶证识别
     */
    public DriverLicenseOCRResponse driverLicenseOcr(MultipartFile file) {
        try {
            String fileBase64 = Base64.encodeAsString(file.getBytes());
            OcrClient client = getOcrClient();
            DriverLicenseOCRRequest req = new DriverLicenseOCRRequest();
            req.setImageBase64(fileBase64);

            // 返回的resp是一个DriverLicenseOCRResponse的实例，与请求对象对应
            DriverLicenseOCRResponse resp = client.DriverLicenseOCR(req);
            return resp;
        } catch (Exception e) {
            throw new GuiguException(ResultCodeEnum.DATA_ERROR);
        }
    }

    /**
     * 创建司机人脸模型
     */
    public String creatDriverFaceModel(DriverInfo driverInfo, String image) {
        try {
            // 实例化一个请求对象,每个接口都会对应一个request对象
            CreatePersonRequest req = new CreatePersonRequest();
            IaiClient client = getIaiClient();
            //设置相关值
            req.setGroupId(cosConfigProperties.getPersonGroupId());
            //基本信息
            req.setPersonId(String.valueOf(driverInfo.getId()));
            req.setGender(Long.parseLong(driverInfo.getGender()));
            req.setQualityControl(4L);
            req.setUniquePersonControl(4L);
            req.setPersonName(driverInfo.getName());
            req.setImage(image);
            // 返回的resp是一个CreatePersonResponse的实例，与请求对象对应
            CreatePersonResponse resp = client.CreatePerson(req);
            return resp.getFaceId();
        } catch (Exception e) {
            log.error("创建人脸模型失败：{}", e.getMessage());
            throw new GuiguException(ResultCodeEnum.DATA_ERROR);
        }
    }
}
